<template>
  <div class="stopword-tab">
    <!-- 顶部工具栏 -->
    <div class="toolbar">
      <div class="left">
        <a-space>
          <a-button @click="onAdd">新增</a-button>
          <a-button :disabled="!selectedRowKeys.length" @click="onBatchDelete">批量删除</a-button>
          <a-button @click="onImport">导入</a-button>
          <a-button @click="onExport">导出</a-button>
        </a-space>
      </div>
      <div class="right">
        <a-input-search v-model:value="keyword" placeholder="输入搜索" enter-button="搜索" @search="onSearch"
          style="width: 260px" />
      </div>
    </div>

    <!-- 中间：表格滚动区（不影响底部分页器） -->
    <div class="table-wrap">
      <a-table :columns="columns" :data-source="pageData" row-key="id" :pagination="false" :row-selection="rowSelection"
        bordered class="table" @change="onTableChange">
        <template #bodyCell="{ column, record }">
          <!-- 名称列 -->
          <template v-if="column.key === 'name'">
            <a class="name-link" @click="onNameClick(record)">{{ record.name }}</a>
          </template>

          <!-- 操作列：编辑 | 删除 | 停用 | 启用（互斥） -->
          <template v-else-if="column.key === 'actions'">
            <span class="ops">
              <a @click="onEdit(record)">编辑</a>
              <span class="sep">|</span>
              <a @click="onDelete(record)">删除</a>
              <span class="sep">|</span>

              <!-- 停用：仅当 enabled=true 可点，否则置灰 -->
              <template v-if="record.enabled">
                <a @click="onDisable(record)">停用</a>
              </template>
              <template v-else>
                <span class="link-disabled">停用</span>
              </template>

              <span class="sep">|</span>

              <!-- 启用：仅当 enabled=false 可点，否则置灰 -->
              <template v-if="!record.enabled">
                <a @click="onEnable(record)">启用</a>
              </template>
              <template v-else>
                <span class="link-disabled">启用</span>
              </template>
            </span>
          </template>
        </template>
      </a-table>
    </div>

    <!-- 底部：全选 + 分页（吸底固定在可视区域下边） -->
    <div class="table-footer">
      <div class="left">
        <a-checkbox :checked="checkAll" @change="onCheckAll">全选</a-checkbox>
      </div>
      <div class="right">
        <span class="stat">本页 {{ pageData.length }} 条，共 {{ total }} 条</span>
        <a-pagination v-model:current="pagination.current" v-model:pageSize="pagination.pageSize" :total="total"
          :page-size-options="['10', '20', '50']" show-size-changer show-less-items show-quick-jumper />
      </div>
    </div>

    <!-- ===== 导入弹框（静态） ===== -->
    <a-modal v-model:visible="importVisible" :footer="null" :mask-closable="false" :keyboard="false" :width="520"
      :title="null" :closable="false" :after-close="resetImport" centered class="import-modal">
      <div class="im-header">
        <div class="title">停用词导入</div>
        <a class="close" @click="closeImport">关闭</a>
      </div>

      <div class="im-body">
        <div class="row">
          <div class="label">选择文件</div>
          <div class="value">
            <template v-if="!file">
              <a-button size="small" class="primary-lite" @click="triggerPick">选择文件</a-button>
              <input ref="fileInput" type="file" accept=".csv,.xls,.xlsx" style="display: none"
                @change="onFileChange" />
            </template>

            <template v-else>
              <a :title="file.name">{{ file.name }}</a>
              <a class="link-del" @click="removeFile">删除</a>
            </template>

            <div class="tip">说明：支持 excel、csv。</div>

            <a-button size="small" class="primary-lite mt8" @click="onDownloadTemplate">
              下载模板
            </a-button>
          </div>
        </div>
      </div>

      <div class="im-footer">
        <a-button type="link" class="cancel" @click="closeImport">取消</a-button>
        <span class="sep">|</span>
        <a-button type="link" class="confirm" :disabled="!file" @click="doImport">导入</a-button>
      </div>
    </a-modal>

    <!-- ===== 导出弹框（新增，样式与截图一致） ===== -->
    <a-modal v-model:visible="exportVisible" :footer="null" :mask-closable="false" :keyboard="false" :width="520"
      :title="null" :closable="false" centered class="export-modal">
      <div class="ex-header">
        <div class="title">停用词导出</div>
        <a class="close" @click="closeExport">关闭</a>
      </div>

      <div class="ex-body">
        <div class="row">
          <div class="label">导出格式</div>
          <div class="value">
            <a-radio-group v-model:value="exportFormat">
              <a-radio value="csv">CSV</a-radio>
              <a-radio value="json">JSON</a-radio>
            </a-radio-group>
          </div>
        </div>
      </div>

      <div class="ex-footer">
        <a-button type="link" class="cancel" @click="closeExport">取消</a-button>
        <span class="sep">|</span>
        <a-button type="link" class="confirm" @click="doExport">导出</a-button>
      </div>
    </a-modal>
  </div>
</template>

<script lang="ts" setup>
import { computed, reactive, ref, nextTick } from "vue";
import { useRouter } from "vue-router";
import { message } from "ant-design-vue";
import type { Key } from "ant-design-vue/es/table/interface";

const router = useRouter();

type Row = {
  id: string | number;
  name: string;
  owner: string;
  publishTime: string;
  enabled: boolean; // 是否启用
};

/** ====== 静态数据 ====== */
const allData = ref<Row[]>([
  { id: 1, name: "了", owner: "张三", publishTime: "2025-09-07 12:30:06", enabled: true },
  { id: 2, name: "的", owner: "李四", publishTime: "2025-09-07 11:44:24", enabled: true },
  { id: 3, name: "a", owner: "王五", publishTime: "2025-09-07 12:30:13", enabled: false },
]);

/** ====== 查询/排序/分页 ====== */
const keyword = ref("");
const pagination = reactive({ current: 1, pageSize: 10 });

const filteredData = computed(() => {
  const k = keyword.value.trim();
  if (!k) return allData.value;
  return allData.value.filter((r) =>
    [r.name, r.owner].some((v) => v?.toLowerCase().includes(k.toLowerCase()))
  );
});

const total = computed(() => filteredData.value.length);

const sortState = reactive<{
  key: keyof Row | "";
  order: "ascend" | "descend" | null;
}>({ key: "", order: null });

const sortedData = computed(() => {
  const arr = [...filteredData.value];
  const { key, order } = sortState;
  if (!key || !order) return arr;
  const sign = order === "ascend" ? 1 : -1;
  return arr.sort((a, b) => {
    const va = a[key], vb = b[key];
    if (key === "publishTime") {
      return (new Date(va as string).getTime() - new Date(vb as string).getTime()) * sign;
    }
    return String(va).localeCompare(String(vb)) * sign;
  });
});

const pageData = computed(() => {
  const start = (pagination.current - 1) * pagination.pageSize;
  const end = start + pagination.pageSize;
  return sortedData.value.slice(start, end);
});

function onSearch() {
  pagination.current = 1;
}
function onTableChange(_: any, __: any, sorter: any) {
  const s = Array.isArray(sorter) ? sorter[0] : sorter;
  sortState.key = (s?.columnKey ?? s?.field ?? "") as any;
  sortState.order = (s?.order ?? null) as any;
}

/** ====== 选择/全选（仅当前页） ====== */
const selectedRowKeys = ref<Key[]>([]);
const rowSelection = computed(() => ({
  selectedRowKeys: selectedRowKeys.value,
  onChange: (keys: Key[]) => (selectedRowKeys.value = keys),
}));
const currentPageKeys = computed<Key[]>(() => pageData.value.map((r) => r.id));
const checkAll = computed(
  () =>
    currentPageKeys.value.length > 0 &&
    currentPageKeys.value.every((k) => selectedRowKeys.value.includes(k))
);
function onCheckAll(e: any) {
  const checked = e?.target?.checked;
  if (checked) {
    const set = new Set([...selectedRowKeys.value, ...currentPageKeys.value]);
    selectedRowKeys.value = Array.from(set);
  } else {
    selectedRowKeys.value = selectedRowKeys.value.filter(
      (k) => !currentPageKeys.value.includes(k)
    );
  }
}

/** ====== 列定义（无 ID 列） ====== */
const columns = [
  { title: "名称", dataIndex: "name", key: "name", sorter: true, columnKey: "name" },
  { title: "添加人", dataIndex: "owner", key: "owner", width: 160, sorter: true, columnKey: "owner" },
  { title: "添加时间", dataIndex: "publishTime", key: "publishTime", width: 220, sorter: true, columnKey: "publishTime" },
  {
    title: "状态", key: "status", width: 120,
    customRender: ({ record }: { record: Row }) => record.enabled ? '启用' : '停用'
  },
  { title: "操作", key: "actions", width: 300 },
];

/** ====== 操作区 ====== */
function onAdd() { router.push({ path: "/stopwordFormAdd" }); }
function onBatchDelete() {
  allData.value = allData.value.filter((r) => !selectedRowKeys.value.includes(r.id as any));
  selectedRowKeys.value = [];
  fixCurrentPage();
}
function onImport() { importVisible.value = true; }
function onExport() { exportVisible.value = true; }
function onNameClick(row: Row) {
  router.push({ path: "/stopwordFormInfo", query: { row: encodeURIComponent(JSON.stringify(row)) } });
}
function onEdit(row: Row) {
  router.push({ path: "/stopwordFormEdit", query: { row: encodeURIComponent(JSON.stringify(row)) } });
}
function onDelete(row: Row) {
  allData.value = allData.value.filter((r) => r.id !== row.id);
  selectedRowKeys.value = selectedRowKeys.value.filter((k) => k !== row.id);
  fixCurrentPage();
}

/** 启用 / 停用 */
function onEnable(row: Row) { row.enabled = true; message.success(`已启用「${row.name}」`); }
function onDisable(row: Row) { row.enabled = false; message.success(`已停用「${row.name}」`); }

/** 删除导致页码越界时修正当前页 */
function fixCurrentPage() {
  nextTick(() => {
    const pages = Math.max(1, Math.ceil(sortedData.value.length / pagination.pageSize));
    if (pagination.current > pages) pagination.current = pages;
  });
}

/** ====== 导入弹框（静态） ====== */
const importVisible = ref(false);
const file = ref<File | null>(null);
const fileInput = ref<HTMLInputElement | null>(null);

function closeImport() { importVisible.value = false; }
function resetImport() { file.value = null; if (fileInput.value) fileInput.value.value = ""; }
function triggerPick() { fileInput.value?.click(); }
function onFileChange(e: Event) {
  const t = e.target as HTMLInputElement;
  if (t.files && t.files.length > 0) file.value = t.files[0];
}
function removeFile() { file.value = null; if (fileInput.value) fileInput.value.value = ""; }
function onDownloadTemplate() {
  const csv = "word,enabled\n的,true\n了,true\nas,true\nthe,true\n";
  const blob = new Blob([csv], { type: "text/csv;charset=utf-8" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = "stopwords_template.csv";
  a.click();
  URL.revokeObjectURL(url);
}
function doImport() {
  if (!file.value) return;
  console.log("导入文件：", file.value.name);
  message.success("导入成功");
  importVisible.value = false;
}

/** ====== 导出弹框（新增） ====== */
const exportVisible = ref(false);
const exportFormat = ref<'csv' | 'json'>('csv');

function closeExport() { exportVisible.value = false; }

const exportRows = computed(() => {
  // 选中优先；未选中则导出“过滤后的全部结果”
  if (selectedRowKeys.value.length) {
    const set = new Set(selectedRowKeys.value as (string | number)[]);
    return allData.value.filter(r => set.has(r.id));
  }
  return filteredData.value;
});

function doExport() {
  const rows = exportRows.value;
  if (!rows.length) {
    message.warning("没有可导出的数据");
    return;
  }
  if (exportFormat.value === 'csv') {
    const header = ["name", "owner", "publishTime", "enabled"];
    const esc = (s: any) => {
      const str = String(s ?? "");
      if (/[",\n]/.test(str)) return `"${str.replace(/"/g, '""')}"`;
      return str;
    };
    const lines = [header.join(",")].concat(
      rows.map(r => [esc(r.name), esc(r.owner), esc(r.publishTime), esc(r.enabled ? "true" : "false")].join(","))
    );
    // 加 BOM 以便 Excel 识别 UTF-8
    const csvContent = "\uFEFF" + lines.join("\n");
    const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8" });
    triggerDownload(blob, "sensitive_words.csv");
  } else {
    const json = JSON.stringify(rows, null, 2);
    const blob = new Blob([json], { type: "application/json;charset=utf-8" });
    triggerDownload(blob, "sensitive_words.json");
  }
  message.success("导出成功");
  exportVisible.value = false;
}

function triggerDownload(blob: Blob, filename: string) {
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = filename;
  a.click();
  URL.revokeObjectURL(url);
}
</script>

<style lang="less" scoped>
/* ===== 核心：三段式布局，底部吸底，表格区域独立滚动 ===== */
.stopword-tab {
  background: #fff;
  border: 1px solid #eaeaea;
  border-radius: 6px;
  padding: 10px;

  display: grid;
  grid-template-rows: auto 1fr auto;
  min-height: 90vh;
  /* 吸底区域始终可见 */
}

/* 顶部工具栏 */
.toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;

  .left :deep(.ant-btn) {
    padding: 0 14px;
    height: 30px;
    border-color: #1677ff;
    color: #1677ff;
  }

  .right {
    display: flex;
    align-items: center;
  }
}

/* 表格滚动容器 */
.table-wrap {
  min-height: 0;
  overflow: auto;
}

/* 表格视觉 & 行高 40px */
.table {
  :deep(.ant-table) {
    border: 1px solid #d9d9d9;
  }

  :deep(.ant-table-container) {
    border-radius: 0;
  }

  /* 表头背景色 #F4F8FD，行高 40 */
  :deep(.ant-table-thead > tr > th) {
    background: #F4F8FD;
    color: #333;
    border-color: #d9d9d9;
    font-weight: 600;
    padding-top: 9px;
    /* 9 + 22 + 9 = 40 */
    padding-bottom: 9px;
  }

  /* 数据行高 40 */
  :deep(.ant-table-tbody > tr > td) {
    border-color: #d9d9d9;
    padding-top: 9px;
    padding-bottom: 9px;
  }

  :deep(.name-link) {
    color: #1677ff;
    cursor: pointer;
    text-decoration: none;
  }

  :deep(.ops .sep) {
    margin: 0 8px;
    color: #999;
  }

  .link-disabled {
    color: #bfbfbf;
    cursor: not-allowed;
    pointer-events: none;
    user-select: none;
  }
}

/* 底部工具条：吸底 + 与截图一致 */
.table-footer {
  position: sticky;
  bottom: 0;
  z-index: 1;
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px 12px;
  border-top: 1px solid #eaeaea;

  .stat {
    margin-right: 12px;
    color: #666;
  }

  .right {
    display: flex;
    align-items: center;
    gap: 8px;
  }
}

/* ========= 导入弹框样式 ========= */
:deep(.import-modal .ant-modal-content) {
  padding: 0;
}

:deep(.import-modal .ant-modal-body) {
  padding: 0;
}

.import-modal {
  .im-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 14px;
    border-bottom: 1px solid #d9d9d9;

    .title {
      font-weight: 600;
    }

    .close {
      color: #1677ff;
      cursor: pointer;
    }
  }

  .im-body {
    padding: 24px 24px 12px;
    min-height: 180px;
    display: flex;
    align-items: flex-start;

    .row {
      display: flex;
      align-items: flex-start;
      gap: 16px;
    }

    .label {
      width: 72px;
      line-height: 28px;
    }

    .value {
      .tip {
        margin-top: 8px;
        color: #888;
      }

      .mt8 {
        margin-top: 12px;
      }
    }

    .primary-lite {
      background: #e6efff;
      border-color: #adc6ff;
    }

    .link-del {
      margin-left: 12px;
      color: #1677ff;
      cursor: pointer;
    }
  }

  .im-footer {
    border-top: 1px solid #d9d9d9;
    padding: 12px 0;
    text-align: center;

    .cancel,
    .confirm {
      color: #1677ff !important;
    }

    .sep {
      margin: 0 8px;
      color: #1677ff;
    }
  }
}

/* ========= 导出弹框样式（新增） ========= */
:deep(.export-modal .ant-modal-content) {
  padding: 0;
}

:deep(.export-modal .ant-modal-body) {
  padding: 0;
}

.export-modal {
  .ex-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 14px;
    border-bottom: 1px solid #d9d9d9;

    .title {
      font-weight: 600;
    }

    .close {
      color: #1677ff;
      cursor: pointer;
    }
  }

  .ex-body {
    padding: 24px 24px 12px;
    min-height: 120px;
    display: flex;
    align-items: flex-start;

    .row {
      display: flex;
      align-items: center;
      gap: 16px;
    }

    .label {
      width: 72px;
      line-height: 28px;
    }
  }

  .ex-footer {
    border-top: 1px solid #d9d9d9;
    padding: 12px 0;
    text-align: center;

    .cancel,
    .confirm {
      color: #1677ff !important;
    }

    .sep {
      margin: 0 8px;
      color: #1677ff;
    }
  }
}
</style>
